package com.xiangshizhineng.tianzhangzhi.app.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiangshizhineng.tianzhangzhi.app.common.R;
import com.xiangshizhineng.tianzhangzhi.app.common.ResultCode;
import com.xiangshizhineng.tianzhangzhi.app.common.base.BaseController;
import com.xiangshizhineng.tianzhangzhi.app.config.Sender;
import com.xiangshizhineng.tianzhangzhi.app.filter.AppToken;
import com.xiangshizhineng.tianzhangzhi.app.model.entity.Event;
import com.xiangshizhineng.tianzhangzhi.app.model.entity.File;
import com.xiangshizhineng.tianzhangzhi.app.model.entity.TzMes;
import com.xiangshizhineng.tianzhangzhi.app.model.response.*;
import com.xiangshizhineng.tianzhangzhi.app.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.xiangshizhineng.tianzhangzhi.app.utils.ConstantUtils.*;

/**
 * @author Administrator
 * @Desc 事件相关
 * @date 2022/1/11 18:45
 */
@RestController
@RequestMapping("/event")
@Slf4j
@Api(tags="事件管理")
public class EventController extends BaseController<Event> {
    @Autowired
    private EventService eventService;
    @Autowired
    EventFileService eventFileService;
    @Autowired
    private UserService userService;
    @Autowired
    private DistrictService districtService;
    @Autowired
    private MesService mesService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private FileService fileService;
    @Autowired
    private Sender sender;

    @ApiOperation(value = "通过id查询", notes = "分页排序模糊查询功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "s",value = "每页的条数", paramType = "query"),
            @ApiImplicitParam(name = "p", value = "请求的页码", paramType = "query"),
            @ApiImplicitParam(name = "createTime", value = "排序字段，true升序(asc),false降序(desc),默认降序显示最新的消息",dataType = "Boolean",paramType = "query"),
            @ApiImplicitParam(name = "eventStatusId", value = "筛选字段，10待审核，11待处理，12已解决",dataType = "Long",paramType = "query"),
            @ApiImplicitParam(name = "id", value = "用户id", dataType = "Long", paramType = "query",required = true),
            @ApiImplicitParam(name = "eventName", value = "根据事件名称模糊查询", dataType = "String", paramType = "query")
    })
    @GetMapping(name = "查询列表")
    @AppToken
    public R<EventResponse> list(@RequestParam(value = "s",required = false,defaultValue = "20")Long s,
                                 @RequestParam(value = "p",required = false,defaultValue = "1")Long p,
                                 @RequestParam(value = "eventName",required = false)String eventName,
                                 @RequestParam(value = "eventStatusId",required = false)Long eventStatusId,
                                 @RequestParam(value = "createTime",required = false,defaultValue = "false")Boolean createTime,
                                 @RequestParam(value = "id")Long id){
        return eventService.eventList(s,p,eventName,eventStatusId,createTime,id);
    }


    @ApiOperation(value = "通过id查看事件详情", notes = "通过id查看事件详情")
    @ApiImplicitParam(name = "id", value = "事件id", dataType = "Long", paramType = "query", required = true)
    @AppToken
    @GetMapping(value = "/details", name="事件详情")
    public R<EventResponse> viewDetails(@RequestParam("id") Long id) {
        Map<String,Object> map = new HashMap(3);
        /*多表联合*/
        EventResponse eventResponse = eventService.queryDetailsById(id);
        List<EventFileResponse> filePath = eventFileService.list(new QueryWrapper<EventFileResponse>()
                .lambda()
                .eq(id!=null&&id.longValue()!=0,EventFileResponse::getEventId,id)
                .eq(EventFileResponse::getPicType,PIC_TYPE_0));
        List<EventFileResponse> filePaths = eventFileService.list(new QueryWrapper<EventFileResponse>()
                .lambda()
                .eq(id!=null&&id.longValue()!=0,EventFileResponse::getEventId,id)
                .eq(EventFileResponse::getPicType,PIC_TYPE_1));
        map.put("eventResponse",eventResponse);
        map.put("filePath",filePath);
        map.put("filePaths",filePaths);
        return R.success(map);
    }
    @ApiOperation(value = "事件上报", notes = "事件上报")
    @ApiImplicitParam(name = "eventResponse",value = "实体类EventResponse",required = true,paramType = "body",dataType = "EventResponse")
    @PostMapping(value = "/report", name="事件上报")
    @AppToken
    public R<EventResponse> viewReport(@RequestBody EventResponse eventResponse) {
//        EventResponse eventResponse = eventResponseT.getEventResponse();
        if (eventResponse.getReportBy()!=null&&eventResponse.getReportBy().longValue()!=0){
            UserResponse userResponse = userService.getById(eventResponse.getReportBy());
//            List<String> file_path = eventResponse.getFilePath();
            List<File> files = eventResponse.getFiles();
            if (eventResponse.getTaskId()!=null && eventResponse.getTaskId().longValue()!=0){
                TaskResponse taskResponse = taskService.allTasksById(new QueryWrapper<TaskResponse>()
                        .lambda()
                        .eq(TaskResponse::getId,eventResponse.getTaskId()));
                eventResponse.setTbId(taskResponse.getTbId());
            }
            if (TZJB_1.equals(userResponse.getTzjb())){
                return R.fail(ResultCode.ERROR.getCode(),"一级田长不能上报");
            }else if (TZJB_2.equals(userResponse.getTzjb())){
                return R.fail(ResultCode.ERROR.getCode(),"二级田长不能上报");
            }else {
                    eventResponse.setCreateTime(new Date());
                    eventResponse.setCb(CB_0);
                    if (eventResponse.getEventReportTypeId() == COMMON_REPORT){
                        try{
                        //查询当前用户审核人
                        UserResponse user1 = userService.getOne(new QueryWrapper<UserResponse>().select("xzqdm").
                                eq("id",eventResponse.getReportBy()));
                        /*通过当前用户行政区划查询行政区表信息*/
                        DistrictResponse dis1 = districtService.getOne(new QueryWrapper<DistrictResponse>().
                                eq("code",user1.getXzqdm()));
                        String level = dis1.getLevel();
                        UserResponse user2 = new UserResponse();
                        if(TZJB_3.equals(level)){
                            /*查询二级行政区划*/
                            DistrictResponse dis2 =districtService.getOne(new QueryWrapper<DistrictResponse>().select("code").
                                    eq("id",dis1.getPid()));
                            user2 = userService.getOne(new QueryWrapper<UserResponse>().select("id").
                                    eq("xzqdm",dis2.getCode()).like("tzxm","田长制办公室"));
                        }else{
                            user2 = userService.getOne(new QueryWrapper<UserResponse>().select("id").
                                    eq("xzqdm",dis1.getCode()).like("tzxm","田长制办公室"));
                        }
                        eventResponse.setReviewer(user2.getId());
                        eventResponse.setHandler(null);
                        eventResponse.setEventStatusId(TO_AUDIT);
                        }catch (Exception e){
                            return R.fail("未查询到上级审核人");
                        }
                }else if (eventResponse.getEventReportTypeId() == FAST_REPORT){
                    eventResponse.setReviewer(null);
                    eventResponse.setEventStatusId(RESOLVED);
                    eventResponse.setHandler(eventResponse.getReportBy());
                }else {return R.fail(ResultCode.ERROR.getCode(),"上报方式出错");}
                boolean i = eventService.save(eventResponse);
                if (i){
                    /*检索出该id下最新的事件*/
                    EventResponse eventsServiceOnly = eventService.getOnly(new QueryWrapper<EventResponse>()
                            .lambda()
                            .eq(EventResponse::getReportBy,eventResponse.getReportBy())
                            .orderByDesc(EventResponse::getCreateTime));
                    List<EventFileResponse> efrList = new ArrayList<>();
                    for (File s : files) {
                        EventFileResponse e = new EventFileResponse();
                        e.setFilePath(s.getFjmc());
                        e.setEventId(eventsServiceOnly.getId());
                        e.setPicType(PIC_TYPE_0);
                        e.setCreateTime(new Date());
                        efrList.add(e);
                    }
                    try {
                        if (eventResponse.getEventReportTypeId() == COMMON_REPORT){
//                        efrList.stream().forEach(t->eventFileService.save(t));
                            for(int a=0; a<efrList.size();a++){
                                eventFileService.save(efrList.get(a));
                                files.get(a).setId(efrList.get(a).getId());
                                files.get(a).setCreateTime(new Date());
                                files.get(a).setXcry(userResponse.getTzxm());
                                files.get(a).setX(eventResponse.getEventX());
                                files.get(a).setY(eventResponse.getEventY());
                                files.get(a).setXcbsm(null!=eventResponse.getTaskId()?eventResponse.getTaskId().toString():"");
                                files.get(a).setTbbsm("".equals(eventResponse.getTbId())?"":eventResponse.getTbId());
                                fileService.save(files.get(a));
                            }
                        }else if (eventResponse.getEventReportTypeId() == FAST_REPORT){
                            for(int a=0; a<efrList.size();a++){
                                eventFileService.save(efrList.get(a));
                                files.get(a).setId(efrList.get(a).getId());
                                files.get(a).setCreateTime(new Date());
                                files.get(a).setXcry(userResponse.getTzxm());
                                files.get(a).setX(eventResponse.getEventX());
                                files.get(a).setY(eventResponse.getEventY());
                                files.get(a).setXcbsm(null!=eventResponse.getTaskId()?eventResponse.getTaskId().toString():"");
                                files.get(a).setTbbsm("".equals(eventResponse.getTbId())?"":eventResponse.getTbId());
                                fileService.save(files.get(a));
                            }
                            for(int a=0; a<efrList.size();a++){
                                efrList.get(a).setPicType(PIC_TYPE_1);
                                eventFileService.save(efrList.get(a));
                                files.get(a).setId(efrList.get(a).getId());
                                files.get(a).setCreateTime(new Date());
                                files.get(a).setXcry(userResponse.getTzxm());
                                files.get(a).setX(eventResponse.getEventX());
                                files.get(a).setY(eventResponse.getEventY());
                                files.get(a).setXcbsm(null!=eventResponse.getTaskId()?eventResponse.getTaskId().toString():"");
                                files.get(a).setTbbsm("".equals(eventResponse.getTbId())?"":eventResponse.getTbId());
                                fileService.save(files.get(a));
                            }
                        }else {return R.fail(ResultCode.ERROR.getCode(),"上报方式出错");}
                    }catch (Exception e){
                        return R.fail("附件表录入失败");
                    }
                    return R.success();
                }else {
                    return R.fail(ResultCode.ERROR.getCode(),"数据录入失败");
                }
            }
        }else {
            return R.fail(ResultCode.ERROR.getCode(),"上报人不存在");
        }
    }
    @ApiOperation(value = "文件上传", notes = "文件上传")
    @ApiImplicitParam(name = "myFiles",value = "MultipartFile[]",required = true,paramType = "String")
    @PostMapping(value = "/fileUpload", name="文件上传")
    @AppToken
    public R fileUpload(MultipartFile[] myFiles) throws Exception {
        Future<List<String>> upload = fileService.upload(myFiles);
        List<String> strings = upload.get();
        return R.success(strings);
    }

    @ApiOperation(value = "解决事件", notes = "待处理事件详情下的解决并提交功能")
    @ApiImplicitParam(name = "eventResponse",value = "EventResponse实体类",required = true,paramType = "body",dataType = "EventResponse")
    @PostMapping(value = "/solve", name="待处理事件模块下的子模块")
    @AppToken
    public R<EventResponse> solveEvent(@RequestBody EventResponse eventResponse){
        boolean i = eventService.update(new UpdateWrapper<EventResponse>()
                .lambda()
                .set(StringUtils.isNotEmpty(eventResponse.getSolveSituation()),EventResponse::getSolveSituation,eventResponse.getSolveSituation())
                .set(EventResponse::getEventStatusId,TO_AUDIT)
                .set(EventResponse::getUpdateTime,new Date())
                .eq(eventResponse.getId()!=null&&eventResponse.getId().longValue()!=0,EventResponse::getId,eventResponse.getId()));
        UserResponse userResponse = userService.getById(eventResponse.getHandler());
        EventResponse eventResponse1 = eventService.getById(eventResponse.getId());
        if (i){
            //事件消息减一
            UpdateWrapper<TzMes> update = new UpdateWrapper<TzMes>();
            update.set("state","1");
            update.eq("id_by_type",eventResponse.getId()).in("type","2","5");
            mesService.update(update);
            List<File> files = eventResponse.getFiles();
            List<EventFileResponse> efrList = new ArrayList<>();
            try {
                for (File s : files) {
                    EventFileResponse e = new EventFileResponse();
                    e.setFilePath(s.getFjmc());
                    e.setEventId(eventResponse.getId());
                    e.setPicType(PIC_TYPE_1);
                    e.setCreateTime(new Date());
                    efrList.add(e);
                }
                for(int a=0; a<efrList.size();a++){
                    eventFileService.save(efrList.get(a));
                    files.get(a).setId(efrList.get(a).getId());
                    files.get(a).setCreateTime(new Date());
                    files.get(a).setXcry(userResponse.getTzxm());
                    files.get(a).setX(eventResponse.getEventX());
                    files.get(a).setY(eventResponse.getEventY());
                    files.get(a).setXcbsm(null!=eventResponse1.getTaskId()?eventResponse1.getTaskId().toString():"");
                    files.get(a).setTbbsm("".equals(eventResponse1.getTbId())?"":eventResponse1.getTbId());
                    fileService.save(files.get(a));
                }
            }catch (Exception e){
                return R.fail("附件表录入失败");
            }
            return R.success("事件解决成功");
        }else{
            return R.fail(ResultCode.ERROR.getCode(),"数据更新失败");
        }
    }
    @ApiOperation(value = "事件审核",notes = "二级田长(田长制办公室)的事件审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "事件id",dataType = "Long",paramType = "query",required = true),
            @ApiImplicitParam(name = "reviewComments",value = "审核意见",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "handler",value = "处理人(id)",dataType = "Long",paramType = "query"),
            @ApiImplicitParam(name = "eventStatusId",value = "审核状态（11待解决 12已解决）",dataType = "Long",paramType = "query",required = true)
    })
    @AppToken
    @PostMapping("/eventAudit")
    public R audit(@RequestParam Long id,
                   @RequestParam(required = false) String reviewComments,
                   @RequestParam(required = false) Long handler,
                   @RequestParam Long eventStatusId){
        boolean i = eventService.update(new UpdateWrapper<EventResponse>()
                .lambda()
                .set(handler!=null&&handler.longValue()!=0&&eventStatusId==TO_BE_SOLVED,EventResponse::getHandler,handler)
                .set(StringUtils.isNotEmpty(reviewComments),EventResponse::getReviewComments,reviewComments)
                .set(EventResponse::getEventStatusId,eventStatusId)
                .set(EventResponse::getReviewerTime,new Date())
                .eq(EventResponse::getId,id));
        if (i){
            TzMes tzMes = new TzMes();
            tzMes.setMessage("收到一条新的事件");
            tzMes.setIdByType(id);
            tzMes.setType("2");
            tzMes.setRoutingKey("transaction_tz");
            tzMes.setUserId(handler);
            sender.sendOtherMes(JSONObject.toJSONString(tzMes));
            return R.success("审核成功");}
        return R.fail(ResultCode.ERROR.getCode(),"审核失败");
    }
    @ApiOperation(value = "子级田长列表",notes = "二级田长下的田长列表")
    @ApiImplicitParam(name = "id",value = "二级田长id",dataType = "Long",paramType = "query",required = true)
    @GetMapping("/childList")
    @AppToken
    public R childList(@RequestParam Long id){
        String xzqdm = userService.getById(id).getXzqdm();
        Long disId = districtService.getOne(new QueryWrapper<DistrictResponse>()
                .lambda()
                .select(DistrictResponse::getId)
                .eq(StringUtils.isNotEmpty(xzqdm),DistrictResponse::getCode,xzqdm)).getId();
        List<String> code = districtService.list(new QueryWrapper<DistrictResponse>()
                        .lambda()
                        .select(DistrictResponse::getCode)
                        .eq(disId!=null&&disId.longValue()!=0,DistrictResponse::getPid,disId))
                /*检索集合中的指定字段*/
                .stream().map(DistrictResponse::getCode).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(code)){
            List<UserResponse> u = userService.list(new QueryWrapper<UserResponse>()
                    .lambda()
                    .select(UserResponse::getId,UserResponse::getTzxm,UserResponse::getTzjb)
                    /*升序排序，倒序comparing().reversed()*/
                    .in(UserResponse::getXzqdm,code)).stream().sorted(Comparator.comparing(UserResponse::getTzjb)).collect(Collectors.toList());
            return R.success(u);
        }
        return R.success(new ArrayList<UserResponse>());
    }

    @ApiOperation(value = "二级田长催办事件", notes = "根据事件id催办事件")
    @ApiImplicitParam(name = "id", value = "事件id", dataType = "Long", paramType = "query", required = true)
    @GetMapping("/updateEventStatus")
    @AppToken
    public R updateEventStatus(@RequestParam Long id,@RequestParam Long userId){
        boolean i = eventService.update(new UpdateWrapper<EventResponse>()
                .lambda()
                .set(EventResponse::getCb,CB_1)
                .set(EventResponse::getUpdateTime,new Date())
                .eq(EventResponse::getId,id));
        if (i){
            try {
                Long handler = eventService.getOne(new QueryWrapper<EventResponse>().select("handler").eq("id",id)).getHandler();
                TzMes tzMes = new TzMes();
                tzMes.setMessage("收到一条催办事件");
                tzMes.setIdByType(id);
                tzMes.setType("5");
                tzMes.setRoutingKey("transaction_tz");
                tzMes.setUserId(handler);
                sender.sendOtherMes(JSONObject.toJSONString(tzMes));
            }catch (Exception e){
                System.out.println("消息推送失败");
                log.error("消息推送失败");
            }
            return R.success("事件催办成功");
        }
        return R.fail(ResultCode.ERROR.getCode(),"状态变更失败");
    }

    @ApiOperation(value = "首页催办事件", notes = "根据事件id查询催办事件信息")
    @ApiImplicitParam(name = "id", value = "事件id", dataType = "Long", paramType = "query", required = true)
    @GetMapping("/cbEvent")
    @AppToken
    public R<List> cbEvent(@RequestParam Long id){
        UpdateWrapper<TzMes> update = new UpdateWrapper<TzMes>();
        update.set("state","1");
        update.eq("id_by_type",id).eq("type","5");
        mesService.update(update);
        EventResponse eventResponse = eventService.cbEvent(id);
        List<EventFileResponse> picList = eventFileService.list(new QueryWrapper<EventFileResponse>()
                .lambda()
                .eq(EventFileResponse::getPicType,PIC_TYPE_0)
                .eq(EventFileResponse::getEventId,id));
        List list  = new ArrayList();
        list.add(eventResponse);
        list.add(picList);
        return R.success(list);
    }


    @ApiOperation(value = "任务详情事件列表", notes = "任务详情事件列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "s", value = "每页的条数", paramType = "query"),
            @ApiImplicitParam(name = "p", value = "请求的页码", paramType = "query"),
            @ApiImplicitParam(name = "id", value = "任务id", dataType = "Long", paramType = "query", required = true),
            @ApiImplicitParam(name = "createTime", value = "创建时间排序(true正序，false倒序)", dataType = "boolean", paramType = "query", required = false)
            })
    @GetMapping("/taskEvent")
    @AppToken
    public R<EventResponse> taskEvent(@RequestParam(value = "s", required = false, defaultValue = "20") Long s,
                                      @RequestParam(value = "p", required = false, defaultValue = "1") Long p,
                                      @RequestParam(value = "id") Long id,
                                      @RequestParam(value = "createTime", required = false,defaultValue = "false") boolean createTime){
        Page<EventResponse> page = new Page<>(p,s);
        Page<EventResponse> pe = eventService.page(page,new QueryWrapper<EventResponse>()
                .lambda()
                .select(EventResponse::getId,EventResponse::getTaskId,EventResponse::getEventName,EventResponse::getEventDes,EventResponse::getEventStatusId)
                .eq(EventResponse::getTaskId,id)
                .orderBy(true,createTime,EventResponse::getCreateTime));
        return R.success(pe);
    }
}
